package hu.monitor.agent.remoting;

import hu.monitor.agent.qualifiers.AgentName;
import hu.monitor.agent.qualifiers.Directory;
import hu.monitor.agent.qualifiers.DirectoryType;
import hu.monitor.agent.qualifiers.ListenAddress;
import hu.monitor.server.AgentMaintenance;
import hu.monitor.server.AgentNotFoundException;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AgentRegistrator extends Thread {
	private static Logger log = LoggerFactory.getLogger(AgentRegistrator.class);

	@Autowired
	@ListenAddress
	private InetSocketAddress clientEndpointAddress;

	@Autowired
	private AgentMaintenance maintenance;

	@Directory(DirectoryType.CONFIGURATION)
	@Autowired
	private File configDirecotry;

	@Autowired
	@AgentName
	private String agentName;

	@PostConstruct
	public void registerAgentEndpoint() throws IOException, AgentNotFoundException {
		this.start();
	}

	@Override
	public void run() {
		Integer agentId = null;
		final Path path = Paths.get(this.configDirecotry.toURI()).resolve("agent.idenitiy");
		try {
			final String content = new String(Files.readAllBytes(path));
			agentId = Integer.parseInt(content);
		} catch (final Exception ex) {

		}

		boolean success = false;
		while (!success) {
			log.info("Registering agent {} with endpoint {}", agentId, this.clientEndpointAddress);
			try {
				agentId = this.maintenance.registerEndpoint(agentId, this.agentName, this.clientEndpointAddress);
				success = true;
			} catch (final AgentNotFoundException ex) {
				log.info("Agent not found on server, shutdown");
				System.exit(1);
			} catch (final Exception ex) {
				log.info("Registration failed, try again: "+ex);
				try {
					Thread.sleep(30000);
				} catch (final InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		try {
			Files.write(path, String.valueOf(agentId).getBytes(), StandardOpenOption.CREATE);
		} catch (final IOException ex) {
			log.error("Error saving agent identitiy to "+path, ex);
		}
	}
}
